﻿/********************************************************************
	created:	2011/05/29
	created:	29:5:2011   21:26
	filename: 	D:\My Documents\Visual Studio 2010\Projects\IntranetMessagerClient\Client\CryptoClient.cs
	file path:	D:\My Documents\Visual Studio 2010\Projects\IntranetMessagerClient\Client
	file base:	CryptoClient
	file ext:	cs
	author:		
	
	purpose:	客户端加密功能
*********************************************************************/
using System;
using System.Security.Cryptography;

namespace Client
{
    internal static class CryptoClient
    {
        private const int KeyLength = 256;

        internal static byte[] DesEncrypt(string key, string iv, byte[] byteMessage)
        {
            using (var des = new DESCryptoServiceProvider())
            {
                if (key == null)
                {
                    return byteMessage;
                }
                var encryptor = des.CreateEncryptor(Convert.FromBase64String(key),
                                                    Convert.FromBase64String(iv));
                return encryptor.TransformFinalBlock(byteMessage, 0, byteMessage.Length);
            }
        }

        internal static byte[] DesDecrypt(string key, string iv, byte[] byteMessage)
        {
            using (var des = new DESCryptoServiceProvider())
            {
                ICryptoTransform encryptor = des.CreateDecryptor(Convert.FromBase64String(key),
                                                                 Convert.FromBase64String(iv));
                return encryptor.TransformFinalBlock(byteMessage, 0, byteMessage.Length);
            }
        }

        internal static void DesGenerateKey(out string key, out string iv)
        {
            using (DES des = new DESCryptoServiceProvider())
            {
                des.GenerateKey();
                des.GenerateIV();
                key = Convert.ToBase64String(des.Key);
                iv = Convert.ToBase64String(des.IV);
            }
        }

        internal static byte[] RsaEncrypt(byte[] byteMessage)
        {
            if (byteMessage.Length > KeyLength - 42)
            {
                return RsaLongEncrypt(byteMessage);
            }
            using (var rsa = new RSACryptoServiceProvider())
            {
                rsa.FromXmlString(KeyPublic);
                return rsa.Encrypt(byteMessage, false);
            }
        }

        private static byte[] RsaLongEncrypt(byte[] byteMessage)
        {
            var resBuffer = new byte[(byteMessage.Length/(KeyLength - 42) + 1)*KeyLength];
            var tempBuffer = new byte[KeyLength - 42];
            const int maxBufLength = KeyLength - 42;
            int arrayLength = 0;
            for (int i = 0; i < byteMessage.Length; i += maxBufLength)
            {
                Array.Copy(byteMessage, i, tempBuffer, 0,
                           ((byteMessage.Length - i) > maxBufLength) ? maxBufLength : (byteMessage.Length - i));
                using (var rsa = new RSACryptoServiceProvider())
                {
                    rsa.FromXmlString(KeyPublic);
                    byte[] tempRsaBuff = rsa.Encrypt(tempBuffer, false);
                    Array.Copy(tempRsaBuff, 0, resBuffer, arrayLength, tempRsaBuff.Length);
                    arrayLength += tempRsaBuff.Length;
                }
            }
            return resBuffer;
        }

        public static bool RsaVerifyHash(byte[] signature, byte[] byteMessage)
        {
            using (var rsa = new RSACryptoServiceProvider())
            {
                rsa.FromXmlString(KeyPublic);
                using (var sha1 = new SHA1Managed())
                {
                    byte[] hash = sha1.ComputeHash(byteMessage);
                    return rsa.VerifyHash(hash, CryptoConfig.MapNameToOID("SHA1"), signature);
                }
            }
        }

        #region RSA密钥对

        private const string KeyPublic =
            "<RSAKeyValue>" +
            "<Modulus>wtt+TFWQEG1Crbwvodp0S5p7ZpQrMnfbTZqqDAKdZnF2NR7NXvQdD/d/+xtuOTSK+sQ9iA+IToYGw9d9Ix+6R0CJRkv4rrEY30TdnTKPN+gnmXIouBCgSHlhUDfIFn1mDh78GX0R3Vb5gxAnA/EYiXAPD8nQWSfLNPChqHAMo7qn9ON4FpGfdBug2GM4oXJZuLuDAHV9manRDCbR2i4cPR4aJvefvyhbSmmJPhPyow7Osuof4g3RC/uu+jhHR/KHTSkMrqDd0hxAYqOgtsAIuKHmZELPtT7gXqlIcBkoMTqiUTngploYGv421ZPGQV7Abm7E5r2mxDQHhWRwVKriYQ==</Modulus>" +
            "<Exponent>AQAB</Exponent>" + "</RSAKeyValue>";

        #endregion
    }
}